import { Injectable } from '@nestjs/common'
import { CreateArticleDto } from './dto/create-article.dto'
import { UpdateArticleDto } from './dto/update-article.dto'
import { PrismaService } from '@/prisma/prisma.service'
import { ConfigService } from '@nestjs/config'
import exceljs from 'exceljs'
import { queryArticleDto } from '@/article/dto/query-article.dto'

@Injectable()
export class ArticleService {
    constructor(private prisma: PrismaService, private config: ConfigService) {}
    create(createArticleDto: CreateArticleDto) {
        return this.prisma.article.create({
            data: createArticleDto,
        })
    }

    async findAll(query: queryArticleDto) {
        const pageSize = +query.pageSize
        const pageNo = +query.pageNo
        const where = {
            title: {
                contains: query.title,
            },
            content: {
                contains: query.content,
            },
        }

        const [article, totalCount] = await Promise.all([
            this.prisma.article.findMany({
                take: pageSize,
                skip: (pageNo - 1) * pageSize,
                where: where,
            }),
            this.prisma.article.count({
                where: where,
            }),
        ])

        return {
            total: totalCount,
            row: article,
        }
    }

    async findOne(id: number) {
        const res = await this.prisma.article.findUnique({
            where: {
                id,
            },
        })
        return res
    }

    update(id: number, updateArticleDto: UpdateArticleDto) {
        return this.prisma.article.update({
            where: {
                id,
            },
            data: updateArticleDto,
        })
    }

    remove(id: number) {
        return this.prisma.article.delete({
            where: {
                id,
            },
        })
    }

    async export() {
        // const where = {
        //   title: {
        //     contains: query.title,
        //   },
        //   content: {
        //     contains: query.content,
        //   },
        // }
        const data = await this.prisma.article.findMany({
            include: {
                category: {
                    select: {
                        title: true,
                    },
                },
            },
        })
        const workbook = new exceljs.Workbook()
        const worksheet = workbook.addWorksheet('文章表')
        worksheet.columns = [
            {
                header: '标题',
                key: 'title',
            },
            {
                header: '内容',
                key: 'content',
            },
            {
                header: '栏目',
                key: 'category:',
            },
        ]
        // // 将数据添加到工作表中
        data.forEach((item, index) => {
            worksheet.addRow([item.title, item.content, item.category?.title])
        })
        const buffer = await workbook.xlsx.writeBuffer()
        return buffer
    }

    async import(categoryId: number, file: Express.Multer.File) {
        const { buffer } = file
        const workbook = new exceljs.Workbook()
        await workbook.xlsx.load(buffer)
        const worksheet = workbook.getWorksheet(1) // 获取excel表格的第一个sheet
        const result = []
        worksheet.eachRow((row, rowNumber) => {
            // 第一行是表头，故从第二行获取数据
            if (rowNumber > 1) {
                const target = {}
                row.eachCell((cell, colNumber) => {
                    this.getProjectCell(target, colNumber, cell.value)
                })
                result.push(target)
            }
        })
        const createMany = await this.prisma.article.createMany({
            data: result.map((item) => {
                return {
                    ...item,
                    categoryId,
                }
            }),
        })
        return createMany
    }

    getProjectCell(target, key, value) {
        const handler = {
            1: (target, value) => {
                target.title = String(value)
            },
            2: (target, value) => {
                target.content = String(value)
            },
        }
        handler[key] && handler[key](target, value)
    }
}
